

#pragma once

#include "net_connection.h"



typedef void message_callback(const char*data,uint32_t len,int msgid,net_connection* clt,void* user_data);
//解决粘包问题
/*
    消息头，每次message进行传输时，在message前加上message_head
*/
struct message_head
{
    int msgid;  //消息序列号
    int msglen; //消息长度
};


//消息头的二进制长度，固定数
#define MESSAGE_HEAD_LEN 8

//消息头+消息体的最大长度限制
#define MESSAGE_LENGTH_LIMIT (65535 - MESSAGE_HEAD_LEN)


/*
    message的路由机制，可以通过msgid触发不同的路由
*/
class message_router{

public:
    message_router():router(),args()
    {
        fprintf(stdout,"message_router init !\n");
    }
    //给一个消息id注册对应的消息处理函数
    int register_msg_router(int msgid,message_callback* mgc,void* user_data){
        if(router.find(msgid)!=router.end()){
            //回调业务已经存在
            return -1;
        }
        router[msgid]=mgc;
        args[msgid]=user_data;
        return 0; 
    } 

    void call(int msgid,uint32_t msglen,const char* data,net_connection* nect){
        //判断msgid对应的回调是否存在
        if (router.find(msgid) == router.end()) {
            fprintf(stderr, "msgid %d is not register!\n", msgid);
            return;
        }

        //直接取出回调函数，执行
        message_callback *callback = router[msgid];
        void *user_data = args[msgid];
        callback(data, msglen, msgid, nect, user_data);
    }
private:
    __gnu_cxx::hash_map<int,message_callback*> router;  //message的路由函数，由messageid到消息处理函数的映射
    __gnu_cxx::hash_map<int,void*> args; //回调函数对应的参数
};